package cruncher;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.Vector;
import java.util.Map.Entry;

public class WordMap {
	private HashMap<String, Integer> words = new HashMap<String, Integer>();
	private ArrayList<Entry<String, Integer>> entList = null;
	private Vector<String> testList = null;
	
	public WordMap()
	{
		
	}
	
	public WordMap(String fileName)
	{
		loadFromFile(fileName);
	}
	
	private void loadFromFile(String fileName)
	{
		try {
			Scanner s = new Scanner(new File(fileName));
			
			while(s.hasNext())
			{
				words.put(s.next(), s.nextInt());
			}
			
			s.close();
			updateList();
		} catch (FileNotFoundException e) {
			System.out.println("Can't load file : " + fileName);
		}
	}
	
	public void saveToFile(String fileName)
	{
		try {
			PrintWriter pw = new PrintWriter(new File(fileName));
			updateList();
			
			for(Map.Entry<String, Integer> entry : entList)
			{
				pw.println(entry.getKey() + " " + entry.getValue());
			}
			
			pw.close();
		} catch (FileNotFoundException e) {
			System.out.println("Can't save file : " + fileName);
		}
	}
	
	private void putWord(String word)
	{
		if(words.containsKey(word))
		{
			words.put(word, words.get(word) + 1);
		}
		else
		{
			words.put(word, 1);
			//System.out.println("Word added : " + word);
		}
	}
	
	public void crunch(String text)
	{
		text = text.toLowerCase();
		char[] cs = text.toCharArray();
		
		int lastPos = -1;
		for(int i = 0; i < cs.length; ++i)
		{
			if(Character.isLowerCase(cs[i]))
			{
				if(lastPos == -1)
					lastPos = i;
			}
			else if(lastPos >= 0)
			{
				if(i - lastPos > 1)
					putWord(text.substring(lastPos, i));
				lastPos = -1;
			}
		}
	}
	
	public void crunchFile(String fileName)
	{
		try {
			Scanner s = new Scanner(new File(fileName));
			while(s.hasNext())
				crunch(s.nextLine());
			s.close();
		} catch (FileNotFoundException e) {
			System.out.println("Error opening file : " + fileName);
		}
		updateList();
	}
	
	private void updateList()
	{
		entList = new ArrayList<Map.Entry<String,Integer>>(words.entrySet());
		Collections.sort(entList, new Comparator<Entry<String, Integer>>() {

			@Override
			public int compare(Entry<String, Integer> o1,
					Entry<String, Integer> o2) {
				return o2.getValue() - o1.getValue();
			}
		});
	}
	
	public String getWord(int i)
	{
		return entList.get(i).getKey();
	}
	
	public int getNumWords()
	{
		return entList.size();
	}
	
	public void printContent()
	{
		if(entList == null) updateList();
		for(Map.Entry<String, Integer> entry : entList)
		{
			System.out.println(entry.getValue() + " : " + entry.getKey());
		}
	}
	
	public Vector<String> getFirstForTesting(int num)
	{
		int n = 0;
		Vector<String> list = new Vector<String>();
		
		for(Map.Entry<String, Integer> entry : entList)
		{
			if(entry.getKey().length() > 2)
			{
				list.add(entry.getKey());
				if(n >= num)
					return list;
			}
		}
		
		Collections.sort(list, new Comparator<String>() {

			@Override
			public int compare(String o1, String o2) {
				return o2.length() - o1.length();
			}
			
		});
		
		System.out.println(list);
		
		return list;
	}
	
	public void prepList(int count)
	{
		testList = getFirstForTesting(count);
		Collections.sort(testList, new Comparator<String>() {

			@Override
			public int compare(String o1, String o2) {
				return o2.length() - o1.length();
			}
			
		});
	}
	
	public void prepList(String[] strings)
	{
		testList = new Vector<String>();
		testList.addAll(Arrays.asList(strings));
		System.out.println(testList);
	}
	
	public int evaluate(String text)
	{
		int score = 0;
		//for(Map.Entry<String, Integer> entry : entList)
		for(String word : testList)
		{
			int sind = -1;
			int count = 0;
			do
			{
				sind++;
				//sind = text.indexOf(entry.getKey(), sind);
				sind = text.indexOf(word, sind);
				if(sind > 0) count++;
			} while(sind >= 0);
			//score += count * entry.getKey().length() * 2;
			if(count > 0)
				text = text.replace(word, "");
			score += count * word.length() * word.length();
			//System.out.println("Score : " + score);
		}
		return score;
	}
	
	public int evaluateAndPrint(String text)
	{
		int score = 0;
		//for(Map.Entry<String, Integer> entry : entList)
		for(String word : testList)
		{
			int sind = -1;
			int count = 0;
			do
			{
				sind++;
				//sind = text.indexOf(entry.getKey(), sind);
				sind = text.indexOf(word, sind);
				if(sind > 0) count++;
			} while(sind >= 0);
			//score += count * entry.getKey().length() * 2;
			score += count * word.length() * word.length();
			if(count > 0)
				text = text.replace(word, "");
			if(count > 0)
				System.out.println(word);
			//System.out.println("Score : " + score);
		}
		return score;
	}
}
